package com.bc.commonentity.log;

import com.bc.commoncore.util.CollectionUtils;
import com.bc.commoncore.util.JsonUtil;
import com.bc.commoncore.util.StringUtils;
import com.bc.commoncore.util.SystemUtils;
import com.bc.commonentity.common.ActionDetailLog;
import com.bc.commonentity.common.ActionLog;
import com.bc.commonentity.enums.LogDetailType;
import org.apache.log4j.Logger;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;

public class LogServiceBLL {
	private static Field[] fields = ActionLog.class.getDeclaredFields();
	private static Field[] actionDetailFields = ActionDetailLog.class.getDeclaredFields();
	private static Logger logger = Logger.getLogger(LogServiceBLL.class);
	public static void SystemActionLog(ActionLog logEngity,List<ActionDetailLog> detailLogs) {
		try {
			//主日志实体为空时，表示异步请求，此时只有detailLogs
			//如果detailLogs有错误，则需要发送报警邮件
			if (logEngity==null) {
				sendDetailMail(detailLogs);
			}

			if(logEngity!=null&&detailLogs!=null){
				if (logEngity.getHasError()==0) {
					//如果最外层的ActionLog没有异常（可能是被吞掉了）
					//但是调用详情List<ActionDetailLog>里面有异常
					//此时将外层的ActionLog标记为异常
					Optional<ActionDetailLog> firstErrorChild=detailLogs.stream().filter(k->k.getHasError()==1).findFirst();
					if (firstErrorChild.isPresent()) {
						logEngity.setStackTrace(firstErrorChild.get().getStackTrace());
						logEngity.setHasError(1);
					}
				}
			}
			
			if (logEngity!=null&&
					logEngity.getStackTrace()!=null&&
					!logEngity.getStackTrace().isEmpty()) {
				String alertBody=getAlertBody(logEngity);
				if (alertBody!=null&&!alertBody.isEmpty()) {
					List<String> ipinfoList = SystemUtils.getLocalIpInfo();
					String appServerIP = JsonUtil.obj2string(ipinfoList);
					String key=logEngity.getSourceSys()+"_"+appServerIP;
					logger.error("方法异常："+alertBody);
					ErrorEmail.sendAlertEmail(key,logEngity.getSourceSys()+"_java项目预警", alertBody);
				}
			}
			LogMqService.asynSendMessage(logEngity,detailLogs);
		} catch (Exception e) {
			logger.error(e.getMessage()+StringUtils.getStackTrace(e));
			String source = "";
			if (logEngity != null) {
				source = logEngity.getSourceSys();
			} else if (detailLogs!=null&&!CollectionUtils.isEmpty(detailLogs)) {
				ActionDetailLog deLogs = detailLogs.get(0);
				if (deLogs != null) {
					source = deLogs.getSourceSys();
				}
			}
			String title=source+ "_SystemActionLog_java项目预警";
			ErrorEmail.sendErrorMail(title,e);
		}
	}
	private static void sendDetailMail(List<ActionDetailLog> detailLogs){
		if (detailLogs==null||detailLogs.size()==0) {
			return;
		}
		try {
			List<ActionDetailLog> errorChilds = getErrorChilds(detailLogs);
			if (errorChilds!=null&&errorChilds.size()>0) {

				StringBuilder sb = new StringBuilder();
				for (ActionDetailLog actionDetailLog : errorChilds) {
					sb.append(getDetailAlertBody(actionDetailLog));
				}
				String alertBody=sb.toString();
				if (alertBody!=null&&!alertBody.isEmpty()) {
					List<String> ipinfoList = SystemUtils.getLocalIpInfo();
					String appServerIP = JsonUtil.obj2string(ipinfoList);
					String key=detailLogs.get(0).getSourceSys()+"_"+appServerIP;
					ErrorEmail.sendAlertEmail(key,detailLogs.get(0).getSourceSys()+"_java项目预警异步", alertBody);
				}
			}
		} catch (Exception e) {
			logger.error(e.getMessage()+StringUtils.getStackTrace(e));
			String title=detailLogs.get(0).getSourceSys()+ "_sendDetailMail_java项目预警";
			ErrorEmail.sendErrorMail(title,e);
		}
	}
	private static List<ActionDetailLog> getErrorChilds(List<ActionDetailLog> detailLogs){
		if (detailLogs==null||detailLogs.size()==0) {
			return null;
		}
		List<ActionDetailLog> errorChilds=new ArrayList<>();
		for(ActionDetailLog log :detailLogs){
			if (log.getHasError()==1){
				if(log.getOptType().intValue()== LogDetailType.postget.value()&&
						(log.getParam().contains("/alert/heart")||
							log.getParam().contains("/quartzhttpservice/"))){
					continue;
				}else{
					errorChilds.add(log);
				}
			}
		}
		return errorChilds;
	}
	private static String getDetailAlertBody(ActionDetailLog logDetailEngity){
		try {
			StringBuilder sb = new StringBuilder();
			String sql="";
			String stackTrace = "";
			Object obj=null;
			String tempvalue="";
			for (Field field : actionDetailFields) {
				field.setAccessible(true);
				obj=field.get(logDetailEngity);
				if (obj!=null) {
					tempvalue=obj.toString();
				}else {
					tempvalue="";
				}
				if (field.getName().equals("stackTrace")) {
					stackTrace = field.getName() + ":"+ tempvalue;
				}else if(field.getName().equals("sql")){
					sql = field.getName() + ":"+ tempvalue+ "\n";
				} else {
					sb.append(field.getName() + ":"+ tempvalue + "\n");
				}
			}
			sb.append(sql);
			sb.append(stackTrace);
			return sb.toString();
		} catch (Exception e) {
			logger.error(e.getMessage()+StringUtils.getStackTrace(e));
		}
		return "";
	}
	private static String getAlertBody(ActionLog logEngity){
		try {
			StringBuilder sb = new StringBuilder();
			String header="";
			String stackTrace = "";
			Object obj=null;
			String tempvalue="";
			for (Field field : fields) {
				field.setAccessible(true);
				obj=field.get(logEngity);
				if (obj!=null) {
					tempvalue=obj.toString();
				}else {
					tempvalue="";
				}
				if (field.getName().equals("stackTrace")) {
					stackTrace = field.getName() + ":"+ tempvalue;
				}else if(field.getName().equals("header")){
					header = field.getName() + ":"+ tempvalue+ "\n";
				} else {
					sb.append(field.getName() + ":"+ tempvalue + "\n");
				}
			}
			sb.append(header);
			sb.append(stackTrace);
			return sb.toString();
		} catch (Exception e) {
			logger.error(e.getMessage()+StringUtils.getStackTrace(e));
		}
		return "";
	}
}
